package presentation.windows;

import java.awt.Font ;
import java.rmi.RemoteException ;
import java.text.SimpleDateFormat ;
import java.util.Date ;

import javax.swing.BorderFactory ;
import javax.swing.ButtonGroup ;
import javax.swing.JButton ;
import javax.swing.JCheckBox ;
import javax.swing.JLabel ;
import javax.swing.JOptionPane ;
import javax.swing.JPanel ;
import javax.swing.JPasswordField ;
import javax.swing.JRadioButton ;
import javax.swing.JTextField ;
import javax.swing.SwingWorker ;
import javax.swing.border.BevelBorder ;

import presentation.UIMember ;
import util.Log ;
import util.NotFoundException ;
import util.Subsystem ;

import com.toedter.calendar.JDateChooser ;

import domain.user.BadPasswordException ;
import domain.user.UnpermittedActionException ;



/**
 * The Class EditProfilePanel is the panel for edit a member's profile
 */
public class EditProfilePanel extends BasePanel
{
	private static final long serialVersionUID = -8072607044691158295L ;
	private JLabel changePasswordLabel;
	private JTextField residenceField;
	private JButton cancelButton;
	private JButton saveButton;
	private JLabel newDobLabel;
	private JTextField dobField;
	private JRadioButton femaleButton;
	private JRadioButton maleButton;
	private JTextField lastNameField;
	private JTextField firstNameField;
	private JLabel dobLabel;
	private JLabel residenceLabel;
	private JLabel genderLabel;
	private JLabel lastNameLabel;
	private JLabel firstNameLabel;
	private JPasswordField verifyPassField;
	private JPasswordField newPassField;
	private JPasswordField oldPassField;
	private JLabel verifyPassLabel;
	private JLabel newPassLabel;
	private JLabel oldPassLabel;
	private JPanel dobPanel;
	private JCheckBox changePassCheckBox;
	private ButtonGroup genderButtons;
	private JDateChooser dateOfBirth ;
	private JCheckBox dobCheckBox;

	private String chosenGender;
	private JLabel editProfileLabel ;

	/**
	 * Constructor
	 * @param sharedData the shared data of all panels
	 */
	public EditProfilePanel(final SharedUIData sharedData)
	{
		super(sharedData);
		this.setPreferredSize(new java.awt.Dimension(735, 566));
		this.chosenGender = "";
		this.initGUI();
	}

	private void cancelButtonButtonHandler()
	{
		this.loadMemberData();
		this.dateOfBirth.setDate(new Date());
		if(this.changePassCheckBox.isSelected())
		{
			this.changePassCheckBox.doClick();
			this.oldPassField.setText("");
			this.newPassField.setText("");
			this.verifyPassField.setText("");
			this.oldPassField.setEditable(false);
			this.newPassField.setEditable(false);
			this.verifyPassField.setEditable(false);
		}

	}

	private void changePassButtonHandler()
	{
		if (this.changePassCheckBox.isSelected())
		{
			this.oldPassField.setEditable(true);
			this.newPassField.setEditable(true);
			this.verifyPassField.setEditable(true);
		}
		else
		{
			this.oldPassField.setEditable(false);
			this.newPassField.setEditable(false);
			this.verifyPassField.setEditable(false);
		}
	}

	private void dobButtonHandler()
	{
		if (this.dobCheckBox.isSelected())
		{
			this.dateOfBirth.setEnabled(true);
		}
		else
		{
			this.dateOfBirth.setEnabled(false);
		}

	}

	private void femaleButtonHandler()
	{
		this.chosenGender = "Female";

	}

	private void initGUI(){

		this.editProfileLabel = new JLabel();
		this.add(this.editProfileLabel);
		this.editProfileLabel.setText("Edit Profile");
		this.editProfileLabel.setBounds(309, 34, 151, 26);
		this.editProfileLabel.setFont(new Font("Californian FB",1,22));

		this.changePasswordLabel = new JLabel();
		this.add(this.changePasswordLabel);
		this.changePasswordLabel.setText("Change password");
		this.changePasswordLabel.setBounds(55, 68, 300, 22);
		this.changePasswordLabel.setFont(new Font("Californian FB",1,16));

		this.changePassCheckBox = new JCheckBox();
		this.add(this.changePassCheckBox);
		this.changePassCheckBox.setBounds(29, 64, 27, 26);

		this.oldPassLabel = new JLabel();
		this.add(this.oldPassLabel);
		this.oldPassLabel.setText("Old Password:");
		this.oldPassLabel.setBounds(30, 103, 97, 14);
		this.oldPassLabel.setFont(new Font("Californian FB",1,16));

		this.newPassLabel = new JLabel();
		this.add(this.newPassLabel);
		this.newPassLabel.setText("New Password:");
		this.newPassLabel.setBounds(30, 130, 117, 14);
		this.newPassLabel.setFont(new Font("Californian FB",1,16));

		this.verifyPassLabel = new JLabel();
		this.add(this.verifyPassLabel);
		this.verifyPassLabel.setText("Verify Password:");
		this.verifyPassLabel.setBounds(30, 160, 122, 14);
		this.verifyPassLabel.setFont(new Font("Californian FB",1,16));

		this.oldPassField = new JPasswordField();
		this.add(this.oldPassField);
		this.oldPassField.setBounds(153, 100, 89, 21);
		this.oldPassField.setEditable(false);
		this.oldPassField.setBorder(BorderFactory.createCompoundBorder(
			null,
			BorderFactory.createBevelBorder(BevelBorder.LOWERED)));

		this.newPassField = new JPasswordField();
		this.add(this.newPassField);
		this.newPassField.setBounds(152, 127, 90, 20);
		this.newPassField.setEditable(false);
		this.newPassField.setBorder(BorderFactory.createCompoundBorder(
			null,
			BorderFactory.createBevelBorder(BevelBorder.LOWERED)));

		this.verifyPassField = new JPasswordField();
		this.add(this.verifyPassField);
		this.verifyPassField.setBounds(152, 153, 89, 21);
		this.verifyPassField.setEditable(false);
		this.verifyPassField.setBorder(BorderFactory.createCompoundBorder(
			null,
			BorderFactory.createBevelBorder(BevelBorder.LOWERED)));

		this.firstNameLabel = new JLabel();
		this.add(this.firstNameLabel);
		this.firstNameLabel.setText("First Name:");
		this.firstNameLabel.setBounds(32, 218, 97, 14);
		this.firstNameLabel.setFont(new Font("Californian FB",1,16));

		this.lastNameLabel = new JLabel();
		this.add(this.lastNameLabel);
		this.lastNameLabel.setText("Last Name:");
		this.lastNameLabel.setBounds(32, 251, 88, 14);
		this.lastNameLabel.setFont(new Font("Californian FB",1,16));

		this.residenceLabel = new JLabel();
		this.add(this.residenceLabel);
		this.residenceLabel.setText("Residence:");
		this.residenceLabel.setBounds(32, 284, 83, 14);
		this.residenceLabel.setFont(new Font("Californian FB",1,16));

		this.genderLabel = new JLabel();
		this.add(this.genderLabel);
		this.genderLabel.setText("Gender:");
		this.genderLabel.setBounds(32, 313, 54, 29);
		this.genderLabel.setFont(new Font("Californian FB",1,16));

		this.dobLabel = new JLabel();
		this.add(this.dobLabel);
		this.dobLabel.setText("Date Of Birth:");
		this.dobLabel.setBounds(29, 360, 97, 18);
		this.dobLabel.setFont(new Font("Californian FB",1,16));

		this.firstNameField = new JTextField();
		this.add(this.firstNameField);
		this.firstNameField.setBounds(163, 215, 112, 21);
		this.firstNameField.setBorder(BorderFactory.createCompoundBorder(
			null,
			BorderFactory.createBevelBorder(BevelBorder.LOWERED)));

		this.lastNameField = new JTextField();
		this.add(this.lastNameField);
		this.lastNameField.setBounds(163, 248, 112, 21);
		this.lastNameField.setBorder(BorderFactory.createCompoundBorder(
			null,
			BorderFactory.createBevelBorder(BevelBorder.LOWERED)));

		this.residenceField = new JTextField();
		this.add(this.residenceField);
		this.residenceField.setBounds(163, 281, 111, 21);
		this.residenceField.setBorder(BorderFactory.createCompoundBorder(
			null,
			BorderFactory.createBevelBorder(BevelBorder.LOWERED)));

		this.genderButtons = new ButtonGroup();

		this.maleButton = new JRadioButton();
		this.add(this.maleButton);
		this.maleButton.setText("Male");
		this.maleButton.setBounds(103, 317, 69, 20);
		this.genderButtons.add(this.maleButton);
		this.maleButton.setFont(new Font("Californian FB",1,16));

		this.femaleButton = new JRadioButton();
		this.add(this.femaleButton);
		this.femaleButton.setText("Female");
		this.femaleButton.setBounds(177, 317, 84, 19);
		this.genderButtons.add(this.femaleButton);
		this.femaleButton.setFont(new Font("Californian FB",1,16));

		this.dobField = new JTextField();
		this.add(this.dobField);
		this.dobField.setBounds(138, 358, 99, 21);
		this.dobField.setBorder(BorderFactory.createCompoundBorder(
			null,
			BorderFactory.createBevelBorder(BevelBorder.LOWERED)));
		this.dobField.setEditable(false);

		this.newDobLabel = new JLabel();
		this.add(this.newDobLabel);
		this.newDobLabel.setText("Choose New:");
		this.newDobLabel.setBounds(297, 359, 106, 20);
		this.newDobLabel.setFont(new Font("Californian FB",1,16));

		this.saveButton = new JButton();
		this.add(this.saveButton);
		this.saveButton.setText("Save Changes");
		this.saveButton.setBounds(189, 441, 125, 25);

		this.cancelButton = new JButton();
		this.add(this.cancelButton);
		this.cancelButton.setText("Reset");
		this.cancelButton.setBounds(380, 441, 93, 27);

		this.dobPanel = new JPanel();
		this.add(this.dobPanel);
		this.dobPanel.setBounds(380, 353, 121, 32);

		this.dobCheckBox = new JCheckBox();
		this.add(this.dobCheckBox);
		this.dobCheckBox.setBounds(273, 359, 21, 18);
		this.dobCheckBox.setFont(new Font("Californian FB",1,12));


		this.dateOfBirth = new JDateChooser();
		this.dobPanel.add(this.dateOfBirth);
		this.dateOfBirth.setEnabled(false);


		this.saveButton.addActionListener(new java.awt.event.ActionListener() {
	         @SuppressWarnings("synthetic-access")
			public void actionPerformed(@SuppressWarnings("unused") final java.awt.event.ActionEvent evt) {
	        	 new SwingWorker<Void,Void>(){
	     			@Override
	     			protected Void doInBackground(){
	     				EditProfilePanel.this.saveButtonHandler();
	     				return null;
	     			}
	     			@Override
	    			protected void done() { /* there is nothing to do here .. */ }
	    		}.execute();
	         }
		 });

		this.cancelButton.addActionListener(new java.awt.event.ActionListener() {
	         @SuppressWarnings("synthetic-access")
			public void actionPerformed(@SuppressWarnings("unused") final java.awt.event.ActionEvent evt) {
	        	 new SwingWorker<Void,Void>(){
	     			@Override
	     			protected Void doInBackground(){
	     				 EditProfilePanel.this.cancelButtonButtonHandler();
	     				return null;
	     			}
	     			@Override
	    			protected void done() { /* there is nothing to do here .. */ }
	    		}.execute();
	         }
		 });


		this.changePassCheckBox.addActionListener(new java.awt.event.ActionListener() {
	         @SuppressWarnings("synthetic-access")
			public void actionPerformed(@SuppressWarnings("unused") final java.awt.event.ActionEvent evt) {
	        	 EditProfilePanel.this.changePassButtonHandler();
	         }
		 });

		this.maleButton.addActionListener(new java.awt.event.ActionListener() {
	         @SuppressWarnings("synthetic-access")
			public void actionPerformed(@SuppressWarnings("unused") final java.awt.event.ActionEvent evt) {
	        	 EditProfilePanel.this.maleButtonHandler();
	         }
		 });

		this.femaleButton.addActionListener(new java.awt.event.ActionListener() {
	         @SuppressWarnings("synthetic-access")
			public void actionPerformed(@SuppressWarnings("unused") final java.awt.event.ActionEvent evt) {
	        	 EditProfilePanel.this.femaleButtonHandler();
	         }
		 });

		this.dobCheckBox.addActionListener(new java.awt.event.ActionListener() {
	         @SuppressWarnings("synthetic-access")
			public void actionPerformed(@SuppressWarnings("unused") final java.awt.event.ActionEvent evt) {
	        	 EditProfilePanel.this.dobButtonHandler();
	         }
		 });
		this.loadMemberData();
	}

	private void loadMemberData()
	{
		try
		{
			long currMemberId = this.getSharedData().getUser().getId();
			UIMember currMember = this.forum.getMemberById(currMemberId);
			this.firstNameField.setText(currMember.getFirstName());
			this.lastNameField.setText(currMember.getLastName());
			this.residenceField.setText(currMember.getResidence());
			String gender = currMember.getGender();
			if (gender.equals("Male"))
			{
				this.genderButtons.setSelected(this.maleButton.getModel(), true);
				this.chosenGender = "Male";
			}
			else
			{
				if (gender.equals("Female"))
				{
					this.genderButtons.setSelected(this.femaleButton.getModel(), true);
					this.chosenGender = "Female";
				}
			}
			this.dobField.setText(currMember.getDateOfBirth());
		}
		catch (RemoteException e)
		{
			Log.getLogger(Subsystem.PRESENTATION_MODEL).info("Remote problems thrown in edit profile panel");
			JOptionPane.showMessageDialog(EditProfilePanel.this,
				"Communication problems, please try again", "error occured", JOptionPane.ERROR_MESSAGE);
			this.notifyCompleted();
			return;
		}
		catch(NotFoundException e)
		{
			JOptionPane.showMessageDialog(EditProfilePanel.this,
				"Something went wrong - please try again later", "error occured", JOptionPane.ERROR_MESSAGE);
			this.notifyCompleted();
			return;
		}

	}

	private void maleButtonHandler()
	{
		this.chosenGender = "Male";

	}

	private void saveButtonHandler()
	{
		long userId = this.getSharedData().getUser().getId();
		if (this.changePassCheckBox.isSelected())
		{
			if (new String(this.oldPassField.getPassword()).equals("")|| new String(this.newPassField.getPassword()).equals("")||
				new String(this.verifyPassField.getPassword()).equals(""))
			{
				JOptionPane.showMessageDialog(EditProfilePanel.this,
				"missing password fields", "error occured", JOptionPane.ERROR_MESSAGE);
				this.oldPassField.setText("");
				this.newPassField.setText("");
				this.verifyPassField.setText("");
				return;
			}
			else
			{
				String newPassword = new String(this.newPassField.getPassword());
				String verifyPassword = new String (this.verifyPassField.getPassword());

				if (newPassword.equals(verifyPassword))
				{
					String oldPassword = new String(this.oldPassField.getPassword());
					try
					{
						this.forum.updatePassword(userId,oldPassword,newPassword);
						Log.getLogger(Subsystem.PRESENTATION_MODEL).finest("user " + userId + " changed his password");
					}
					catch(NotFoundException e)
					{
						JOptionPane.showMessageDialog(EditProfilePanel.this,
							"Something went wrong - please try again later", "error occured", JOptionPane.ERROR_MESSAGE);
						this.notifyCompleted();
						return;
					}
					catch(BadPasswordException e)
					{
						JOptionPane.showMessageDialog(EditProfilePanel.this,
							"Wrong Password!", "error occured", JOptionPane.ERROR_MESSAGE);
						return;
					}
					catch (RemoteException e)
					{
						Log.getLogger(Subsystem.PRESENTATION_MODEL).info("Remote problems thrown in edit profile panel");
						JOptionPane.showMessageDialog(EditProfilePanel.this,
							"Communication problems, please try again", "error occured", JOptionPane.ERROR_MESSAGE);
						this.notifyCompleted();
						return;
					}
				}
				else
				{
					JOptionPane.showMessageDialog(EditProfilePanel.this,
						"your new password doesn't match verify password", "error occured", JOptionPane.ERROR_MESSAGE);
					return;
				}
			}
		}
		String newFirstName = this.firstNameField.getText();
		String newLastName = this.lastNameField.getText();
		String newResidence = this.residenceField.getText();
		SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
		String dob = "";
		if (this.dobCheckBox.isSelected())
		{
			if (this.dateOfBirth.getDate()!=null)
			{
				dob = df.format(this.dateOfBirth.getDate());
			}
		}
		try
		{
			this.forum.updateMemberDetails(userId,newFirstName,newLastName,dob,this.chosenGender
				,newResidence);
			Log.getLogger(Subsystem.PRESENTATION_MODEL).finest("user " + userId + " has changed his profile details");
		}
		catch (RemoteException e)
		{
			Log.getLogger(Subsystem.PRESENTATION_MODEL).info("Remote problems thrown in edit profile panel");
			JOptionPane.showMessageDialog(EditProfilePanel.this,
				"Communication problems, please try again", "error occured", JOptionPane.ERROR_MESSAGE);
			this.notifyCompleted();
			return;
		}
		catch(NotFoundException e)
		{
			JOptionPane.showMessageDialog(EditProfilePanel.this,
				"Something went wrong - please try again later", "error occured", JOptionPane.ERROR_MESSAGE);
			this.notifyCompleted();
			return;
		}
		catch (UnpermittedActionException e)
		{
			JOptionPane.showMessageDialog(EditProfilePanel.this,
				"You are not allowed to edit profile", "error occured", JOptionPane.ERROR_MESSAGE);
			this.notifyCompleted();
			return;
		}


		JOptionPane.showMessageDialog(EditProfilePanel.this, "Update Profile successful");
		this.notifyCompleted();

	}

}
